home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / ftp-rl.taz / ftp-rl / ftp / main.c.old < prev    next >
Encoding:
Text File  |  1992-10-07  |  8.6 KB  |  492 lines

  1. /*
  2.  * Copyright (c) 1985, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. char copyright[] =
  22. "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
  23.  All rights reserved.\n";
  24. #endif /* not lint */
  25.  
  26. #ifndef lint
  27. static char sccsid[] = "@(#)main.c    5.16 (Berkeley) 6/1/90";
  28. #endif /* not lint */
  29.  
  30. /*
  31.  * FTP User Program -- Command Interface.
  32.  */
  33. #include "ftp_var.h"
  34. #include <sys/socket.h>
  35. #include <sys/ioctl.h>
  36. #include <sys/types.h>
  37.  
  38. #include <arpa/ftp.h>
  39.  
  40. #include <signal.h>
  41. #include <stdio.h>
  42. #include <errno.h>
  43. #include <ctype.h>
  44. #include <netdb.h>
  45. #include <pwd.h>
  46. #include "pathnames.h"
  47.  
  48. uid_t    getuid();
  49. sig_t    intr();
  50. sig_t    lostpeer();
  51. extern    char *home;
  52. char    *getlogin();
  53.  
  54. main(argc, argv)
  55.     char *argv[];
  56. {
  57.     register char *cp;
  58.     int top;
  59.     struct passwd *pw = NULL;
  60.     char homedir[MAXPATHLEN];
  61.  
  62.     sp = getservbyname("ftp", "tcp");
  63.     if (sp == 0) {
  64.         fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
  65.         exit(1);
  66.     }
  67.     doglob = 1;
  68.     interactive = 1;
  69.     autologin = 1;
  70.     argc--, argv++;
  71.     while (argc > 0 && **argv == '-') {
  72.         for (cp = *argv + 1; *cp; cp++)
  73.             switch (*cp) {
  74.  
  75.             case 'd':
  76.                 options |= SO_DEBUG;
  77.                 debug++;
  78.                 break;
  79.             
  80.             case 'v':
  81.                 verbose++;
  82.                 break;
  83.  
  84.             case 't':
  85.                 trace++;
  86.                 break;
  87.  
  88.             case 'i':
  89.                 interactive = 0;
  90.                 break;
  91.  
  92.             case 'n':
  93.                 autologin = 0;
  94.                 break;
  95.  
  96.             case 'g':
  97.                 doglob = 0;
  98.                 break;
  99.  
  100.             default:
  101.                 fprintf(stdout,
  102.                   "ftp: %c: unknown option\n", *cp);
  103.                 exit(1);
  104.             }
  105.         argc--, argv++;
  106.     }
  107.     fromatty = isatty(fileno(stdin));
  108.     if (fromatty)
  109.         verbose++;
  110.     cpend = 0;    /* no pending replies */
  111.     proxy = 0;    /* proxy not active */
  112.     crflag = 1;    /* strip c.r. on ascii gets */
  113.     sendport = -1;    /* not using ports */
  114.     /*
  115.      * Set up the home directory in case we're globbing.
  116.      */
  117.     cp = getlogin();
  118.     if (cp != NULL) {
  119.         pw = getpwnam(cp);
  120.     }
  121.     if (pw == NULL)
  122.         pw = getpwuid(getuid());
  123.     if (pw != NULL) {
  124.         home = homedir;
  125.         (void) strcpy(home, pw->pw_dir);
  126.     }
  127.     if (argc > 0) {
  128.         if (setjmp(toplevel))
  129.             exit(0);
  130.         (void) signal(SIGINT, intr);
  131.         (void) signal(SIGPIPE, lostpeer);
  132.         setpeer(argc + 1, argv - 1);
  133.     }
  134.     top = setjmp(toplevel) == 0;
  135.     if (top) {
  136.         (void) signal(SIGINT, intr);
  137.         (void) signal(SIGPIPE, lostpeer);
  138.     }
  139.     for (;;) {
  140.         cmdscanner(top);
  141.         top = 1;
  142.     }
  143. }
  144.  
  145. sig_t
  146. intr()
  147. {
  148.  
  149.     longjmp(toplevel, 1);
  150. }
  151.  
  152. sig_t
  153. lostpeer()
  154. {
  155.     extern FILE *cout;
  156.     extern int data;
  157.  
  158.     if (connected) {
  159.         if (cout != NULL) {
  160.             (void) shutdown(fileno(cout), 1+1);
  161.             (void) fclose(cout);
  162.             cout = NULL;
  163.         }
  164.         if (data >= 0) {
  165.             (void) shutdown(data, 1+1);
  166.             (void) close(data);
  167.             data = -1;
  168.         }
  169.         connected = 0;
  170.     }
  171.     pswitch(1);
  172.     if (connected) {
  173.         if (cout != NULL) {
  174.             (void) shutdown(fileno(cout), 1+1);
  175.             (void) fclose(cout);
  176.             cout = NULL;
  177.         }
  178.         connected = 0;
  179.     }
  180.     proxflag = 0;
  181.     pswitch(0);
  182. }
  183.  
  184. /*char *
  185. tail(filename)
  186.     char *filename;
  187. {
  188.     register char *s;
  189.     
  190.     while (*filename) {
  191.         s = rindex(filename, '/');
  192.         if (s == NULL)
  193.             break;
  194.         if (s[1])
  195.             return (s + 1);
  196.         *s = '\0';
  197.     }
  198.     return (filename);
  199. }
  200. */
  201. /*
  202.  * Command parser.
  203.  */
  204. cmdscanner(top)
  205.     int top;
  206. {
  207.     register struct cmd *c;
  208.     struct cmd *getcmd();
  209.     extern int help();
  210.  
  211.     if (!top)
  212.         (void) putchar('\n');
  213.     for (;;) {
  214.         if (fromatty) {
  215.             printf("ftp> ");
  216.             (void) fflush(stdout);
  217.         }
  218.         if (gets(line) == 0) {
  219.             if (feof(stdin) || ferror(stdin))
  220.                 quit();
  221.             break;
  222.         }
  223.         if (line[0] == 0)
  224.             break;
  225.         makeargv();
  226.         if (margc == 0) {
  227.             continue;
  228.         }
  229.         c = getcmd(margv[0]);
  230.         if (c == (struct cmd *)-1) {
  231.             printf("?Ambiguous command\n");
  232.             continue;
  233.         }
  234.         if (c == 0) {
  235.             printf("?Invalid command\n");
  236.             continue;
  237.         }
  238.         if (c->c_conn && !connected) {
  239.             printf ("Not connected.\n");
  240.             continue;
  241.         }
  242.         (*c->c_handler)(margc, margv);
  243.         if (bell && c->c_bell)
  244.             (void) putchar('\007');
  245.         if (c->c_handler != help)
  246.             break;
  247.     }
  248.     (void) signal(SIGINT, intr);
  249.     (void) signal(SIGPIPE, lostpeer);
  250. }
  251.  
  252. struct cmd *
  253. getcmd(name)
  254.     register char *name;
  255. {
  256.     extern struct cmd cmdtab[];
  257.     register char *p, *q;
  258.     register struct cmd *c, *found;
  259.     register int nmatches, longest;
  260.  
  261.     longest = 0;
  262.     nmatches = 0;
  263.     found = 0;
  264.     for (c = cmdtab; p = c->c_name; c++) {
  265.         for (q = name; *q == *p++; q++)
  266.             if (*q == 0)        /* exact match? */
  267.                 return (c);
  268.         if (!*q) {            /* the name was a prefix */
  269.             if (q - name > longest) {
  270.                 longest = q - name;
  271.                 nmatches = 1;
  272.                 found = c;
  273.             } else if (q - name == longest)
  274.                 nmatches++;
  275.         }
  276.     }
  277.     if (nmatches > 1)
  278.         return ((struct cmd *)-1);
  279.     return (found);
  280. }
  281.  
  282. /*
  283.  * Slice a string up into argc/argv.
  284.  */
  285.  
  286. int slrflag;
  287.  
  288. makeargv()
  289. {
  290.     char **argp;
  291.     char *slurpstring();
  292.  
  293.     margc = 0;
  294.     argp = margv;
  295.     stringbase = line;        /* scan from first of buffer */
  296.     argbase = argbuf;        /* store from first of buffer */
  297.     slrflag = 0;
  298.     while (*argp++ = slurpstring())
  299.         margc++;
  300. }
  301.  
  302. /*
  303.  * Parse string into argbuf;
  304.  * implemented with FSM to
  305.  * handle quoting and strings
  306.  */
  307. char *
  308. slurpstring()
  309. {
  310.     int got_one = 0;
  311.     register char *sb = stringbase;
  312.     register char *ap = argbase;
  313.     char *tmp = argbase;        /* will return this if token found */
  314.  
  315.     if (*sb == '!' || *sb == '$') {    /* recognize ! as a token for shell */
  316.         switch (slrflag) {    /* and $ as token for macro invoke */
  317.             case 0:
  318.                 slrflag++;
  319.                 stringbase++;
  320.                 return ((*sb == '!') ? "!" : "$");
  321.                 /* NOTREACHED */
  322.             case 1:
  323.                 slrflag++;
  324.                 altarg = stringbase;
  325.                 break;
  326.             default:
  327.                 break;
  328.         }
  329.     }
  330.  
  331. S0:
  332.     switch (*sb) {
  333.  
  334.     case '\0':
  335.         goto OUT;
  336.  
  337.     case ' ':
  338.     case '\t':
  339.         sb++; goto S0;
  340.  
  341.     default:
  342.         switch (slrflag) {
  343.             case 0:
  344.                 slrflag++;
  345.                 break;
  346.             case 1:
  347.                 slrflag++;
  348.                 altarg = sb;
  349.                 break;
  350.             default:
  351.                 break;
  352.         }
  353.         goto S1;
  354.     }
  355.  
  356. S1:
  357.     switch (*sb) {
  358.  
  359.     case ' ':
  360.     case '\t':
  361.     case '\0':
  362.         goto OUT;    /* end of token */
  363.  
  364.     case '\\':
  365.         sb++; goto S2;    /* slurp next character */
  366.  
  367.     case '"':
  368.         sb++; goto S3;    /* slurp quoted string */
  369.  
  370.     default:
  371.         *ap++ = *sb++;    /* add character to token */
  372.         got_one = 1;
  373.         goto S1;
  374.     }
  375.  
  376. S2:
  377.     switch (*sb) {
  378.  
  379.     case '\0':
  380.         goto OUT;
  381.  
  382.     default:
  383.         *ap++ = *sb++;
  384.         got_one = 1;
  385.         goto S1;
  386.     }
  387.  
  388. S3:
  389.     switch (*sb) {
  390.  
  391.     case '\0':
  392.         goto OUT;
  393.  
  394.     case '"':
  395.         sb++; goto S1;
  396.  
  397.     default:
  398.         *ap++ = *sb++;
  399.         got_one = 1;
  400.         goto S3;
  401.     }
  402.  
  403. OUT:
  404.     if (got_one)
  405.         *ap++ = '\0';
  406.     argbase = ap;            /* update storage pointer */
  407.     stringbase = sb;        /* update scan pointer */
  408.     if (got_one) {
  409.         return(tmp);
  410.     }
  411.     switch (slrflag) {
  412.         case 0:
  413.             slrflag++;
  414.             break;
  415.         case 1:
  416.             slrflag++;
  417.             altarg = (char *) 0;
  418.             break;
  419.         default:
  420.             break;
  421.     }
  422.     return((char *)0);
  423. }
  424.  
  425. #define HELPINDENT (sizeof ("directory"))
  426.  
  427. /*
  428.  * Help command.
  429.  * Call each command handler with argc == 0 and argv[0] == name.
  430.  */
  431. help(argc, argv)
  432.     int argc;
  433.     char *argv[];
  434. {
  435.     extern struct cmd cmdtab[];
  436.     register struct cmd *c;
  437.  
  438.     if (argc == 1) {
  439.         register int i, j, w, k;
  440.         int columns, width = 0, lines;
  441.         extern int NCMDS;
  442.  
  443.         printf("Commands may be abbreviated.  Commands are:\n\n");
  444.         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  445.             int len = strlen(c->c_name);
  446.  
  447.             if (len > width)
  448.                 width = len;
  449.         }
  450.         width = (width + 8) &~ 7;
  451.         columns = 80 / width;
  452.         if (columns == 0)
  453.             columns = 1;
  454.         lines = (NCMDS + columns - 1) / columns;
  455.         for (i = 0; i < lines; i++) {
  456.             for (j = 0; j < columns; j++) {
  457.                 c = cmdtab + j * lines + i;
  458.                 if (c->c_name && (!proxy || c->c_proxy)) {
  459.                     printf("%s", c->c_name);
  460.                 }
  461.                 else if (c->c_name) {
  462.                     for (k=0; k < strlen(c->c_name); k++) {
  463.                         (void) putchar(' ');
  464.                     }
  465.                 }
  466.                 if (c + lines >= &cmdtab[NCMDS]) {
  467.                     printf("\n");
  468.                     break;
  469.                 }
  470.                 w = strlen(c->c_name);
  471.                 while (w < width) {
  472.                     w = (w + 8) &~ 7;
  473.                     (void) putchar('\t');
  474.                 }
  475.             }
  476.         }
  477.         return;
  478.     }
  479.     while (--argc > 0) {
  480.         register char *arg;
  481.         arg = *++argv;
  482.         c = getcmd(arg);
  483.         if (c == (struct cmd *)-1)
  484.             printf("?Ambiguous help command %s\n", arg);
  485.         else if (c == (struct cmd *)0)
  486.             printf("?Invalid help command %s\n", arg);
  487.         else
  488.             printf("%-*s\t%s\n", HELPINDENT,
  489.                 c->c_name, c->c_help);
  490.     }
  491. }
  492.